//
//  ZallPickerView.m
//  ZJS
//
//  Created by so on 16/6/17.
//  Copyright © 2016年 zall. All rights reserved.
//

#import "ZallPickerView.h"
#import "UIView+ZallAdditions.h"
#import "UIControl+ZallAddition.h"
#import "NSObject+ZallAdditions.h"

@interface ZallPickerView () <UIPickerViewDataSource, UIPickerViewDelegate> {
    CGRect _preRect;
    CGRect _fromRect;
    NSMutableArray <__kindof ZallPickerItem *> *_selectedItems;
}
@property (strong, nonatomic, readonly) UIButton *maskButton;
@property (assign, nonatomic, getter=isShowControls) BOOL showControls;
@property (strong, nonatomic, readonly, nonnull) ZallPickToolView *toolView;
@property (assign, nonatomic) CGFloat rowHeight;
@property (strong, nonatomic, readonly, nonnull) UIPickerView *pickerView;
@property (assign, nonatomic) NSInteger components;
@property (copy, nonatomic) NSArray <ZallPickerItem *> *items;
@end

@implementation ZallPickerView
@synthesize delegate = _delegate;
@synthesize components = _components;
@synthesize maskButton = _maskButton;
@synthesize toolView = _toolView;
@synthesize pickerView = _pickerView;

#pragma mark - life cycle
- (void)dealloc {
    
}

- (instancetype)initWithFrame:(CGRect)frame components:(NSInteger)components items:(NSArray <__kindof ZallPickerItem *> * _Nonnull)items {
    self = [super initWithFrame:frame];
    if(self) {
        _preRect = frame;
        _showControls = YES;
        _rowHeight = 40.0f;
        self.components = components;
        self.items = items;
        [self addSubview:self.pickerView];
    }
    return (self);
}
#pragma mark -

#pragma mark - override
- (void)layoutSubviews {
    [super layoutSubviews];
    CGRect inFrame = UIEdgeInsetsInsetRect(self.bounds, self.contentInsets);
    self.toolView.hidden = ![self isShowControls];
    self.toolView.top = 0;
    self.toolView.centerX = CGRectGetMidX(inFrame);
    self.pickerView.frame = CGRectMake(CGRectGetMinX(inFrame), self.toolView.bottom, CGRectGetWidth(inFrame), CGRectGetHeight(inFrame) - self.toolView.height);
}
#pragma mark -

#pragma mark - setter
- (void)setComponents:(NSInteger)components {
    [self willChangeValueForKey:@"components"];
    _components = components;
    [self didChangeValueForKey:@"components"];
    _selectedItems = [[NSMutableArray alloc] initWithCapacity:_components];
    for(NSInteger index = 0; index < components; index ++) {
        [_selectedItems addObject:[ZallPickerItem item]];
    }
}

- (void)setShowControls:(BOOL)showControls {
    [self willChangeValueForKey:@"showControls"];
    _showControls = showControls;
    [self didChangeValueForKey:@"showControls"];
    self.toolView.height = showControls ? 40.0f : 0.0f;
    [self setNeedsLayout];
}

- (void)setRowHeight:(CGFloat)rowHeight {
    [self willChangeValueForKey:@"rowHeight"];
    _rowHeight = rowHeight;
    [self didChangeValueForKey:@"rowHeight"];
    [self.pickerView reloadAllComponents];
}

- (void)setDelegate:(id<ZallPickerViewDelegate>)delegate {
    [self willChangeValueForKey:@"delegate"];
    _delegate = delegate;
    [self didChangeValueForKey:@"delegate"];
    [self.pickerView reloadAllComponents];
}
#pragma mark -

#pragma mark - getter
- (UIButton *)maskButton {
    if(!_maskButton) {
        _maskButton = [[UIButton alloc] init];
        _maskButton.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.05f];
        __weak typeof(self) weak_self = self;
        [_maskButton setActionBlock:^(UIControl *control) {
            weak_self.maskButton.enabled = NO;
            [weak_self dismissAnimated:YES];
        } delayDuration:1.0f delayBlock:^(UIControl *control) {
            weak_self.maskButton.enabled = YES;
        }];
    }
    return (_maskButton);
}

- (ZallPickToolView *)toolView {
    if(!_toolView) {
        _toolView = [[ZallPickToolView alloc] initWithFrame:CGRectMake(0, 0, self.width, 40.0f)];
        _toolView.backgroundColor = [UIColor whiteColor];
        _toolView.borderLineWidth = 1.0f / [UIScreen mainScreen].scale;
        _toolView.borderColor = [UIColor lightGrayColor];
        _toolView.borderStyle = ZallBorderLineTop | ZallBorderLineBottom;
        [_toolView.leftButton addTarget:self action:@selector(leftButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
        [_toolView.rightButton addTarget:self action:@selector(rightButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:_toolView];
    }
    return (_toolView);
}

- (UIPickerView *)pickerView {
    if(!_pickerView) {
        _pickerView = [[UIPickerView alloc] init];
        _pickerView.dataSource = self;
        _pickerView.delegate = self;
    }
    return (_pickerView);
}
#pragma mark -

#pragma mark - public
- (void)selectText:(NSString * _Nonnull)text inComponent:(NSInteger)component animated:(BOOL)animated {
    if(!text || ![text isKindOfClass:[NSString class]]) {
        return;
    }
    NSArray *subItems = self.items;
    for(NSInteger index = 0; index < component; index ++) {
        NSInteger selectedRow = [self.pickerView selectedRowInComponent:index];
        ZallPickerItem *item = [subItems safeObjectAtIndex:selectedRow];
        if(!item || ![item isKindOfClass:[ZallPickerItem class]] || !item.items) {
            return;
        }
        subItems = item.items;
    }
    for(NSInteger index = 0; index < [subItems count]; index ++) {
        ZallPickerItem *item = [subItems safeObjectAtIndex:index];
        if(item.attributedText && [item.attributedText string] && [[item.attributedText string] isEqualToString:text]) {
            [self.pickerView selectRow:index inComponent:component animated:animated];
            [_selectedItems safeReplaceObjectAtIndex:component withObject:item];
            return;
        }
    }
}

- (NSArray <__kindof ZallPickerItem *> * _Nonnull)selectedItems {
    return ([_selectedItems copy]);
}

- (void)showInView:(UIView * _Nullable)view {
    if(!view || ![view isKindOfClass:[UIView class]]) {
        view = [[UIApplication sharedApplication] keyWindow];
    }
    CGRect fromRect = CGRectMake(0, view.height + self.height, view.width, self.height);
    [self showFromRect:fromRect inView:view animated:YES];
}

- (void)showFromRect:(CGRect)rect inView:(UIView * _Nullable)view animated:(BOOL)animated {
    if(!view || ![view isKindOfClass:[UIView class]]) {
        view = [[UIApplication sharedApplication] keyWindow];
    }
    self.maskButton.frame = view.bounds;
    self.maskButton.alpha = 0.0f;
    if(!self.maskButton.superview) {
        [view addSubview:self.maskButton];
    }
    if(!self.superview) {
        [view addSubview:self];
    }
    self.frame = _fromRect = rect;
    [self.pickerView reloadAllComponents];
    CGRect toRect = CGRectMake(0, view.height - self.height, self.width, self.height);
    [UIView animateWithDuration:0.5f animations:^{
        self.maskButton.alpha = 1.0f;
        self.frame = toRect;
    }];
}

- (void)dismiss {
    [self dismissAnimated:YES];
}

- (void)dismissAnimated:(BOOL)animated {
    [UIView animateWithDuration:(animated ? 0.5f : 0) animations:^{
        self.maskButton.alpha = 0.0f;
        self.frame = _fromRect;
    } completion:^(BOOL finished) {
        if(finished) {
            if(self.maskButton.superview) {
                [self.maskButton removeFromSuperview];
            }
            if(self.superview) {
                [self removeFromSuperview];
            }
        }
    }];
}
#pragma mark -

#pragma mark - actions
- (void)leftButtonTouched:(UIButton *)sender {
    if(self.delegate && [self.delegate respondsToSelector:@selector(pickerView:leftButtonTouched:)]) {
        [self.delegate pickerView:self leftButtonTouched:sender];
        return;
    }
    [self dismiss];
}

- (void)rightButtonTouched:(UIButton *)sender {
    if(self.delegate && [self.delegate respondsToSelector:@selector(pickerView:rightButtonTouched:)]) {
        [self.delegate pickerView:self rightButtonTouched:sender];
        return;
    }
    [self dismiss];
}
#pragma mark -

#pragma mark - <UIPickerViewDataSource>
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return (self.components);
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    NSArray *subItems = self.items;
    for(NSInteger index = 0; index < component; index ++) {
        NSInteger selectedRow = [self.pickerView selectedRowInComponent:index];
        ZallPickerItem *item = [subItems safeObjectAtIndex:selectedRow];
        if(!item || ![item isKindOfClass:[ZallPickerItem class]] || !item.items) {
            return (0);
        }
        subItems = item.items;
    }
    return ([subItems count]);
}
#pragma mark -

#pragma mark - <UIPickerViewDelegate>
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
    if(self.delegate && [self.delegate respondsToSelector:@selector(pickerView:widthForComponent:)]) {
        return ([self.delegate pickerView:pickerView widthForComponent:component]);
    }
    return (pickerView.width / MAX(1, _components));
}

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
    if(self.delegate && [self.delegate respondsToSelector:@selector(pickerView:rowHeightForComponent:)]) {
        return ([self.delegate pickerView:pickerView rowHeightForComponent:component]);
    }
    return (self.rowHeight);
}

- (nullable NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component {
    if(self.delegate && [self.delegate respondsToSelector:@selector(pickerView:attributedTitleForRow:forComponent:)]) {
        return ([self.delegate pickerView:pickerView attributedTitleForRow:row forComponent:component]);
    }
    NSArray *subItems = self.items;
    for(NSInteger index = 0; index < component; index ++) {
        NSInteger selectedRow = [self.pickerView selectedRowInComponent:index];
        ZallPickerItem *item = [subItems safeObjectAtIndex:selectedRow];
        if(!item || ![item isKindOfClass:[ZallPickerItem class]] || !item.items) {
            return (0);
        }
        subItems = item.items;
    }
    ZallPickerItem *item = (ZallPickerItem *)[subItems safeObjectAtIndex:row];
    [_selectedItems safeReplaceObjectAtIndex:component withObject:item];
    return ([item attributedText]);
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    if(self.delegate && [self.delegate respondsToSelector:@selector(pickerView:didSelectRow:inComponent:)]) {
        [self.delegate pickerView:pickerView didSelectRow:row inComponent:component];
    }
    
    {
        NSArray *subItems = self.items;
        for(NSInteger index = 0; index < component; index ++) {
            NSInteger selectedRow = [self.pickerView selectedRowInComponent:index];
            ZallPickerItem *item = [subItems safeObjectAtIndex:selectedRow];
            if(!item || ![item isKindOfClass:[ZallPickerItem class]] || !item.items) {
                return;
            }
            subItems = item.items;
        }
        ZallPickerItem *item = (ZallPickerItem *)[subItems safeObjectAtIndex:row];
        if(!item || ![item isKindOfClass:[ZallPickerItem class]]) {
            return;
        }
        [_selectedItems safeReplaceObjectAtIndex:component withObject:item];
        
        if(self.delegate && [self.delegate respondsToSelector:@selector(pickerView:didSelectRow:inComponent:attributedText:)]) {
            [self.delegate pickerView:self didSelectRow:row inComponent:component attributedText:item.attributedText];
        }
    }
}
#pragma mark -

@end



@implementation ZallPickToolView
@synthesize leftButton = _leftButton;
@synthesize rightButton = _rightButton;
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if(self) {
        [self addSubview:self.leftButton];
        [self addSubview:self.rightButton];
    }
    return (self);
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.leftButton.left = self.contentInsets.left;
    self.rightButton.right = self.width - self.contentInsets.right;
    self.leftButton.centerY = self.rightButton.centerY = CGRectGetMidY(UIEdgeInsetsInsetRect(self.bounds, self.contentInsets));
}

- (UIButton *)leftButton {
    if(!_leftButton) {
        _leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60.0f, 30.0f)];
        _leftButton.backgroundColor = [UIColor clearColor];
        _leftButton.titleLabel.font = [UIFont systemFontOfSize:15];
        [_leftButton setTitleColor:UIColorFromHexRGB(0xff6600) forState:UIControlStateNormal];
        [_leftButton setTitle:@"取消" forState:UIControlStateNormal];
    }
    return (_leftButton);
}

- (UIButton *)rightButton {
    if(!_rightButton) {
        _rightButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60.0f, 30.0f)];
        _rightButton.backgroundColor = [UIColor clearColor];
        _rightButton.titleLabel.font = [UIFont systemFontOfSize:15];
        [_rightButton setTitleColor:UIColorFromHexRGB(0xff6600) forState:UIControlStateNormal];
        [_rightButton setTitle:@"完成" forState:UIControlStateNormal];
    }
    return (_rightButton);
}
@end



@implementation ZallPickerItem

+ (instancetype)itemWithText:(NSString * _Nonnull)text {
    return ([self itemWithText:text items:nil]);
}

+ (instancetype)itemWithText:(NSString * _Nonnull)text items:(NSArray <__kindof ZallPickerItem *>  * _Nullable)items {
    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text];
    return ([self itemWithAttributedText:attributedText items:items]);
}

+ (instancetype)itemWithAttributedText:(NSAttributedString * _Nonnull)attributedText items:(NSArray <__kindof ZallPickerItem *>  * _Nullable)items {
    ZallPickerItem *item = [[self alloc] init];
    item.attributedText = attributedText;
    item.items = items;
    return (item);
}

@end
